<template>
  <div style="display: flex; justify-content: end; gap: .25em;">
    <template v-if="OpGte('标注')">
      <a-tooltip>
        <template #title>添加并应用当前时间段 (+)</template>
        <a-button @click="handleAdd">
          <template #icon><plus-outlined /></template>
          添加
        </a-button>
      </a-tooltip>
      <a-tooltip>
        <template #title>添加后，从当前时间段之后开始</template>
        <a-button @click="handleAddAdvance">
          <template #icon><swap-right-outlined /></template>
          添加 & 前进
        </a-button>
      </a-tooltip>
      <a-tooltip>
        <template #title>清空动作</template>
        <a-button @click="handleClear">
          <template #icon><clear-outlined /></template>
          清空
        </a-button>
      </a-tooltip>
    </template>
  </div>
  <a-table
    class="action-table"
    :columns="columns"
    :data-source="layers"
    :pagination="false"
    row-key="id"
  >
  </a-table>
</template>

<script lang="jsx" setup>
import { inject, nextTick, ref } from 'vue';
import { SwapRightOutlined, PlusOutlined, ClearOutlined, AimOutlined, EnvironmentOutlined, DeleteOutlined, EditOutlined } from '@ant-design/icons-vue';
import * as utils from 'video-action/libs/utils.js';
import { xsToOpts } from '@/util/index.js';
import { Modal } from 'ant-design-vue';
import { UUID } from '@/util/rnd';
import { Comment } from './api/use-comment';

const primaryMainElem = inject('primaryMainElem');
const video = inject('video');
const labels = inject('labels');
const OpGte = inject('OpGte');
const annotationState = inject('annotationState');

/** @type {import('vue').Ref<ImgSegmnt.Layer[]>} */
const layers = inject('layers');

/** @type {import('vue').Ref<ImgSegmnt.Comment[]>} */
const comments = inject('comments');
const commentModalProps = inject('commentModalProps');
const delComment = inject('delComment');
const classes = inject('classes');

const findComment = inject('findComment');

const filterOption = (input, opt) => opt.value.includes(input);

const columns = [
  {
    width: '8%',
    align: 'center',
    title: '起始',
    dataIndex: 'start',
    sorter: (a, b) => (a.start != b.start ? a.start - b.start : a.end - b.end),
    customRender: ({ record }) => (
      OpGte('标注')
      ? <a-input-number
          v-model:value={record.start}
          style="width: 100%;"
        >
        </a-input-number>
      : record.start
    ),
  },
  {
    width: '8%',
    align: 'center',
    title: '结束',
    dataIndex: 'end',
    sorter: (a, b) => (a.end != b.end ? a.end - b.end : a.start - b.start),
    customRender: ({ record }) => (
      OpGte('标注')
      ? <a-input-number
          v-model:value={record.end}
          style="width: 100%;"
        >
        </a-input-number>
      : record.end
    ),
  },
  {
    width: '8%',
    align: 'center',
    title: '时长',
    customRender: ({ record }) => utils.toFixed2(record.end - record.start),
  },
  {
    width: '20%',
    align: 'center',
    title: '动作',
    dataIndex: 'action',
    customRender: ({ record }) => (
      OpGte('标注')
      ? <a-select
          v-model:value={record.action}
          placeholder="请选择标签"
          show-search
          dropdown-match-select-width={false}
          filter-option={filterOption}
          options={
            xsToOpts(classes.value)
            .map(item =>
              Object.assign(item, { disabled: labels.value.includes(item.value) })
            )
          }
          style="width: 100%;"
        >
        </a-select>
      : record.action
    ),
  },
  {
    align: 'center',
    title: '描述',
    customRender: ({ record }) => {
      const comment = findComment(record);
      return (
        <div style="display: flex; gap: .5em;">
          <span style="flex: 1;">{comment?.remark ?? '--'}</span>
          {OpGte('审核') && (
          comment
          ? <a-button
              title="删除批注"
              type="danger"
              ghost={true}
              onClick={
                () => Modal.confirm({
                  centered: true,
                  content: '确定删除此批注？',
                  onOk: () => delComment(comment)
                })
              }
            >
              {{ icon: () => <DeleteOutlined /> }}
            </a-button>
          : <a-button
              title="编辑批注"
              onClick={() => {
                comments.value.push(Comment(record));
                commentModalProps.value.visible = true;
              }}>
              {{ icon: () => <EditOutlined /> }}
            </a-button>
          )}
        </div>
      )
    },
  },
  {
    width: 170,
    align: 'center',
    title: '操作',
    dataIndex: 'operation',
    customRender: ({ record }) => (
      <div style="display: flex; gap: .5em; justify-content: center;">
        <a-tooltip>
        {{
          title: () => '跳到动作的时间段',
          default: () => (
            <a-button onClick={() => handleGoto(record)}>
              {{ icon: () => <AimOutlined />}}
            </a-button>
          )
        }}
        </a-tooltip>
        {
          OpGte('标注') &&
          <a-tooltip>
          {{
            title: () => '「起始」和「结束」应用当前时间段',
            default: () => (
              <a-button onClick={() => handleSet(record)}>
                {{ icon: () => <EnvironmentOutlined /> }}
              </a-button>
            )
          }}
          </a-tooltip>
        }
        {
          OpGte('标注') &&
          <a-button
            type="danger"
            ghost={true}
            onClick={() => handleDelete(record)}
          >
            {{ icon: () => <DeleteOutlined /> }}
          </a-button>
        }
      </div>
    ),
  }
];

function handleAdd() {
  layers.value.push({
    id: UUID(),
    start: utils.index2time(video.value.fps, annotationState.value.frame.left),
    end: utils.index2time(video.value.fps, annotationState.value.frame.right),
    action: void 0,
  });
  
  nextTick().then(() => primaryMainElem.value.scrollTo(0, document.body.scrollHeight));
};

function handleAddAdvance() {
  handleAdd();
  const nextFrame =
    annotationState.value.frame.right + 1 > video.value.frames
      ? annotationState.value.frame.right
      : annotationState.value.frame.right + 1
  // right frame -> next keyframe from action end frame + 1
  let min = video.value.frames
  let nearestKeyframe = nextFrame
  for (let i = 0; i < annotationState.value.keyframeList.length; i++) {
    let distance = annotationState.value.keyframeList[i] - nextFrame
    if (distance > 0 && distance < min) {
      min = distance
      nearestKeyframe = annotationState.value.keyframeList[i]
    }
  }
  annotationState.value.frame.right = nearestKeyframe
  // left frame -> left frame => action end frame + 1
  annotationState.value.frame.left = nextFrame
}
function handleClear() {
  Modal.confirm({
    centered: true,
    content: '确定清空？',
    onOk: () => {
      layers.value.splice(0);
      comments.value.splice(0);
    }
  });
}

/// filter
const showFilter = ref(false)
const actionFilterList = ref({})
classes.value.forEach((label) => {
  actionFilterList.value[label.id] = true
})

function handleGoto(row) {
  if (typeof row.start === 'number') {
    annotationState.value.frame.left = utils.time2index(video.value.fps, row.start);
  }
  if (typeof row.end === 'number') {
    annotationState.value.frame.right = utils.time2index(video.value.fps, row.end);
  }
}

function handleSet(row) {
  row.start = utils.index2time(video.value.fps, annotationState.value.frame.left)
  row.end = utils.index2time(video.value.fps, annotationState.value.frame.right)
}

function handleDelete(row) {
  Modal.confirm({
    centered: true,
    content: '确定删除此行？',
    onOk: () => {
      layers.value.splice(
        layers.value.findIndex(item => item == row),
        1
      );
    },
  });
}
</script>

<style>
.action-table .ant-table-tbody > tr > td {
  padding-top: 6px;
  padding-bottom: 6px;
  border-bottom-color: transparent
}
</style>